package com.ctosb.classviewer.clazz.attr.frame;

import com.ctosb.classviewer.ClassReader;
import com.ctosb.classviewer.clazz.AbstractParse;
import com.ctosb.classviewer.clazz.Parseable;
import com.ctosb.classviewer.clazz.attr.frame.variable.*;
import lombok.Data;
import lombok.experimental.Accessors;

import java.util.HashMap;
import java.util.Map;

/**
 *
 */
@Data
@Accessors(chain = true)
public class Verification_type_info extends AbstractParse {

    private BaseVariableInfo variableInfo;
//    private Top_variable_info top_variable_info;
//    private Integer_variable_info integer_variable_info;
//    private Float_variable_info float_variable_info;
//    private Long_variable_info long_variable_info;
//    private Double_variable_info double_variable_info;
//    private Null_variable_info null_variable_info;
//    private UninitializedThis_variable_info uninitializedThis_variable_info;
//    private Object_variable_info object_variable_info;
//    private Uninitialized_variable_info uninitialized_variable_info;

    private static Map<Byte, Class<? extends BaseVariableInfo>> map = new HashMap<>();

    static {
        map.put((byte) 0, Top_variable_info.class);
        map.put((byte) 1, Integer_variable_info.class);
        map.put((byte) 2, Float_variable_info.class);
        map.put((byte) 3, Double_variable_info.class);
        map.put((byte) 4, Long_variable_info.class);
        map.put((byte) 5, Null_variable_info.class);
        map.put((byte) 6, UninitializedThis_variable_info.class);
        map.put((byte) 7, Object_variable_info.class);
        map.put((byte) 8, Uninitialized_variable_info.class);
    }

    @Override
    public Verification_type_info parse(ClassReader classReader) {
        byte type = classReader.readByte();

        Class<? extends BaseVariableInfo> clazz = map.get(type);
        if (clazz == null) {
            throw new UnsupportedOperationException("un support verification variable type " + type);
        }
        try {
            variableInfo = clazz.newInstance()
                    .setTag(type)
                    .parse(classReader, getClassFile());
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("parse variable info exception.", e);
        }
        return this;
    }
}
